import { Config } from "@/entities/Config";
import { Dataset } from "@/entities/Dataset";
import { initORM } from "@/utils";
import { NextApiRequest, NextApiResponse } from "next";
import { getCurrentUser } from "./user";
import { getApp, getUserListOfApp } from "./app";
import { User } from "@/entities/User";
import { App } from "@/entities/App";
import { pickData, sleep } from "@/utils/base";

export async function getDatasets(req: NextApiRequest) {
  const em = await initORM();
  const query = req.query ?? {};
  const conditions = {
    ...(query.appid ? { app: { id: Number(query.appid) } } : {}),
    ...(query.name ? { name: { $like: `%${query.name}%` } } : {}),
    ...(query.disabled ? { disabled: Number(query.disabled) } : {}),
  };
  // console.log("🚀 ~ getConfigs ~ conditions:", conditions);
  const datasets = await em.find(Dataset, conditions, {
    populate: ["app", "editor"],
  });

  return {
    success: true as const,
    message: "Query Datasets success",
    data: { datasets },
  };
}

export async function getDataset(req: NextApiRequest) {
  const datasetid = req.query.datasetid || req.body?.datasetid;
  //   const curUser = await getCurrentUser(req);

  const em = await initORM();
  const dataset = await em.findOne(Dataset, Number(datasetid));

  if (!dataset) {
    return {
      success: false,
      data: {},
      message: "Dataset not found",
    };
  }

  return {
    success: true,
    data: dataset,
    message: "Query dataset success",
  };
}

export async function updateDataset(
  req: NextApiRequest,
  res: NextApiResponse<APIRes>
) {
  const { datasetid, name, disabled, introduce, app } = req.body ?? {};

  const datasetResult = await getDataset(req);

  if (!datasetResult.success) {
    res.status(400).json(datasetResult as APIRes);
    return;
  }

  const dataset = datasetResult.data as Dataset;

  const keys = ["name", "introduce", "app", "value", "defValueId"] as const;

  keys.forEach((key) => {
    if (req.body[key] !== undefined) {
      Object.assign(dataset, { [key]: req.body[key] as string });
    }
  });

  const em = await initORM();

  const curUser = await getCurrentUser(req);
  if (!curUser) {
    res.status(400).json({
      success: false,
      data: {},
      message: "User not found",
    });
  } else {
    const userRef = em.getReference(User, curUser.id, { wrapped: true });
    dataset.editor = userRef;
  }

  await em.persistAndFlush(dataset);

  res.status(200).json({
    success: true,
    data: dataset,
    message: "Update dataset success",
  });
}

export async function createDataset(
  req: NextApiRequest,
  res: NextApiResponse<APIRes>
) {
  const em = await initORM();
  const curUser = await getCurrentUser(req);
  if (!curUser) {
    res.status(400).json({
      success: false,
      data: {},
      message: "User not found",
    });
    return;
  }

  const curAppResult = await getApp(req);
  if (!curAppResult.success) {
    res.status(400).json(curAppResult as APIRes);
    return;
  }

  const curApp = curAppResult.data as App;

  const data = Object.assign({}, req.body ?? {});
  if (Array.isArray(data.value)) {
    data.value = JSON.stringify(data.value);
  }
  const dataset = await em.create(
    Dataset,
    Object.assign({ creator: curUser, editor: curUser, app: curApp }, data)
  );
  await em.persistAndFlush(dataset);
  await sleep(1);

  res.status(200).json({
    success: true,
    data: pickData(dataset, ["id", "name"]),
    message: "Dataset created",
  });
}
